import { Avatar, Button, Dropdown, Table, Tag, message } from 'antd';

import '../index.scss';
import type { MenuProps, TableColumnsType } from 'antd';
import Search from 'antd/es/input/Search';

import type { IntegratedStoreModalRef } from '@/components/common/IntegratedStoreModal';
import InfiniIcon from '@/components/common/icon';
import { GoogleDriveSVG, HugoSVG, NotionSVG, YuqueSVG } from '@/components/icons';
import useQueryParams from '@/hooks/common/queryParams';
import { deleteConnector, searchConnector } from '@/service/api/connector';

import Icon, { EllipsisOutlined, ExclamationCircleOutlined, FilterOutlined, PlusOutlined } from '@ant-design/icons';

import { formatESSearchResult } from '@/service/request/es';
import { Api } from '@/types/api';
import { getServer } from '@/store/slice/server';

type Connector = Api.Datasource.Connector;

const ConnectorSettings = memo(() => {
  const [queryParams, setQueryParams] = useQueryParams();

  const { t } = useTranslation();  
  const server = useAppSelector(getServer);
  
  const nav = useNavigate();

  const { addSharesToData, isEditorOwner, hasEdit, isResourceShare } = useResource();
  const resourceType = 'connector';

  const { hasAuth } = useAuth();

  const permissions = {
    read: hasAuth('coco#connector/read'),
    create: hasAuth('coco#connector/create'),
    update: hasAuth('coco#connector/update'),
    delete: hasAuth('coco#connector/delete')
  };

  const onMenuClick = ({ key, record }: any) => {
    switch (key) {
      case '2':
        window?.$modal?.confirm({
          content: t('page.connector.delete.confirm', { name: record.name }),
          icon: <ExclamationCircleOutlined />,
          onCancel() {},
          onOk() {
            deleteConnector(record.id).then(res => {
              if (res.data?.result === 'deleted') {
                message.success(t('common.deleteSuccess'));
              }
              // reload data
              setQueryParams(old => {
                return {
                  ...old,
                  t: new Date().valueOf()
                };
              });
            });
          },
          title: t('common.tip')
        });

        break;
      case '1':
        nav(`/connector/edit/${record.id}`, { state: record });
        break;
    }
  };
  const columns: TableColumnsType<Connector> = [
    {
      dataIndex: 'name',
      minWidth: 150,
      ellipsis: true,
      render: (name, record) => {
        const isShare = isResourceShare(record);

        let shareIcon;

        if (isShare) {
          shareIcon = (
            <div className='flex-shrink-0 flex-grow-0'>
              <SvgIcon
                className='text-#999'
                localIcon='share'
              />
            </div>
          );
        }

        let svgIcon = null;
        switch (record.processor?.name) {
          case 'google_drive':
            svgIcon = GoogleDriveSVG;
            break;
          case 'yuque':
            svgIcon = YuqueSVG;
            break;
          case 'notion':
            svgIcon = NotionSVG;
            break;
          case 'hugo_site':
            svgIcon = HugoSVG;
            break;
        }
        return (
          <div className='flex items-center gap-1'>
            <IconWrapper className='h-20px w-20px flex-shrink-0 flex-grow-0'>
              {record.icon ? (
                <InfiniIcon
                  height='1em'
                  src={record.icon}
                  width='1em'
                  server={server}
                />
              ) : (
                <Icon component={svgIcon} />
              )}
            </IconWrapper>
            <span className='ant-table-cell-ellipsis max-w-150px'>{name}</span>
            {shareIcon}
          </div>
        );
      },
      title: t('page.connector.columns.name')
    },
    {
      dataIndex: 'owner',
      title: t('page.datasource.labels.owner'),
      render: (value, record) => {
        if (!value) return '-';
        return (
          <div className='flex overflow-hidden'>
            <Avatar.Group
              max={{ count: 1 }}
              size='small'
            >
              <AvatarLabel
                data={value}
                showCard={true}
              />
            </Avatar.Group>
          </div>
        );
      }
    },
    {
      dataIndex: 'shares',
      title: t('page.datasource.labels.shares'),
      render: (value, record) => {
        if (!value) return '-';
        return (
          <Shares
            record={record}
            title={record.name}
            resource={{
              resource_type: resourceType,
              resource_id: record.id
            }}
            onSuccess={() => fetchData(queryParams)}
          />
        );
      }
    },
    {
      dataIndex: 'category',
      minWidth: 200,
      title: t('page.connector.columns.category')
    },
    {
      dataIndex: 'description',
      minWidth: 100,
      title: t('page.connector.columns.description'),
      ellipsis: true
    },
    {
      dataIndex: 'tags',
      minWidth: 100,
      render: (value: string[]) => {
        return (value || []).map((tag, index) => {
          return <Tag key={index}>{tag}</Tag>;
        });
      },
      title: t('page.connector.columns.tags')
    },
    {
      fixed: 'right',
      hidden: !permissions.update && !permissions.delete,
      render: (_, record) => {
        const items: MenuProps['items'] = [];
        if (permissions.read && permissions.update && hasEdit(record)) {
          items.push({
            key: '1',
            label: t('common.edit')
          });
        }
        if (permissions.delete && isEditorOwner(record)) {
          items.push({
            key: '2',
            label: t('common.delete')
          });
        }
        if (items.length === 0) return null;
        return (
          <Dropdown menu={{ items, onClick: ({ key }) => onMenuClick({ key, record }) }}>
            <EllipsisOutlined />
          </Dropdown>
        );
      },
      title: t('common.operation'),
      width: '90px'
    }
  ];

  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(false);

  const [keyword, setKeyword] = useState();

  const fetchData = async queryParams => {
    setLoading(true);
    const res = await searchConnector(queryParams);
    if (res?.data) {
      const newData = formatESSearchResult(res?.data);
      if (newData.data.length > 0) {
        const resources = newData.data.map(item => ({
          resource_id: item.id,
          resource_type: resourceType
        }));
        const dataWithShares = await addSharesToData(newData.data, resources);
        if (dataWithShares) {
          newData.data = dataWithShares;
        }
      }
      setData(newData);
    }
    setLoading(false);
  };

  useEffect(() => {
    fetchData(queryParams);
  }, [queryParams]);

  useEffect(() => {
    setKeyword(queryParams.query);
  }, [queryParams.query]);

  const onAddClick = () => {
    nav(`/connector/new`);
  };

  const handleTableChange = (pagination, filters, sorter) => {
    setQueryParams(params => {
      return {
        ...params,
        size: pagination.pageSize,
        from: (pagination.current - 1) * pagination.pageSize
      };
    });
  };

  const onSearchClick = (query: string) => {
    setQueryParams(oldParams => {
      return {
        ...oldParams,
        from: query === oldParams.query ? oldParams.from : 0,
        query,
        t: new Date().valueOf()
      };
    });
  };

  const integratedStoreModalRef = useRef<IntegratedStoreModalRef>(null);

  return (
    <ListContainer>
      <div className='mb-4 mt-4 flex items-center justify-between'>
        <Search
          addonBefore={<FilterOutlined />}
          className='max-w-500px'
          enterButton={t('common.refresh')}
          value={keyword}
          onChange={e => setKeyword(e.target.value)}
          onSearch={onSearchClick}
        />
        {permissions.create && (
          <Button
            icon={<PlusOutlined />}
            type='primary'
            onClick={() => {
            integratedStoreModalRef.current?.open('connector');
          }}
          >
            {t('common.add')}
          </Button>
        )}
      </div>
      <Table<Connector>
        columns={columns}
        dataSource={data.data}
        loading={loading}
        rowKey='id'
        size='middle'
        pagination={{
          current: Math.floor(queryParams.from / queryParams.size) + 1,
          pageSize: queryParams.size,
          showSizeChanger: true,
          showTotal: (total, range) => `${range[0]}-${range[1]} of ${total} items`,
          total: data?.total?.value || data?.total
        }}
        onChange={handleTableChange}
      />
      <IntegratedStoreModal ref={integratedStoreModalRef} />
    </ListContainer>
  );
});

export default ConnectorSettings;
